package com.maya.service;

import java.util.Date;
import java.util.List;

import org.bson.types.ObjectId;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.QueryResults;
import org.mongodb.morphia.query.UpdateOperations;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.maya.dao.AnswerDAO;
import com.maya.dao.LogDAO;
import com.maya.dao.QuestionDAO;
import com.maya.dao.TimeLineDAO;
import com.maya.dao.TopicDAO;
import com.maya.dao.UserDAO;
import com.maya.model.Answer;
import com.maya.model.AnswerLog;
import com.maya.model.Log;
import com.maya.model.Log.Action;
import com.maya.model.Question;
import com.maya.model.QuestionLog;
import com.maya.model.TimeLine;
import com.maya.model.Topic;
import com.maya.model.User;
import com.maya.model.UserLog;



@Service
public class UserService  {
    
	@Autowired
	private UserDAO udao;
	
	@Autowired
	private QuestionDAO qdao;
	
	@Autowired
	private LogDAO ldao;
	
	@Autowired
	private TimeLineDAO tdao;
	
	@Autowired
	private AnswerDAO adao;
	
	@Autowired
	private TopicDAO topicdao;
	
    public Question ask(User u,String title, String content) {
        Question question = new Question();
        question.setLastModifiedAt(new Date());
        question.setTitle(title);
        question.setBody(content);
        question.setAuthorId(u.getId());
        question.setLastModifiedAt(new Date());
        question.setCreatedAt(new Date());
        question.setAuthorId(u.getId());
        question.setAuthorName(u.getName());
        u.setAskCount(u.getAskCount()+1);
        

        
        qdao.save(question);
        
        
        System.out.println(question.getId() + "问题保存到数据库了，" + u.getName() + "问的");
        
        udao.save(u);
        
        Log qlog = new QuestionLog();
        qlog.setOwnerId(u.getId());
        qlog.setTitle(question.getTitle());
        qlog.setQuestionId(question.getId());
        qlog.setTargetId(question.getId());
        
        qlog.setAction(Action.NEW);
        
        ldao.save(qlog);
        
        return question;
    }

    // 关注某人
    public void followPerson(User from ,User to) {
        if (!from.equals(to) && !from.getFollowingIds().contains(to.getId())
                && !to.getFollowerIds().contains(from.getId())) {
            from.getFollowingIds().add(to.getId());
            to.getFollowerIds().add(from.getId());
            
            udao.save(from);
            udao.save(to);
            
            //log
            
            Log ulog = new UserLog();
            ulog.setOwnerId(from.getId());
            ulog.setTitle(from.getName());
            ulog.setTargetId(to.getId());
            ulog.setTargetAttr(to.getName());
            ulog.setAction(Action.FOLLOW_USER);
            
            
            ldao.save(ulog);
            add2FollowersTimeLine(from,ulog);
        }
    }

    // 取消关注某人
    public void unFollowPerson(User from,User to) {
        
        from.getFollowingIds().remove(to.getId());
        to.getFollowerIds().remove(from.getId());
        

        // 更新自己的列表
        Query<User> updateQuery = udao.createQuery().field("_id")
                .equal(from.getId());
        UpdateOperations<User> ops = udao.createUpdateOperations()
                .removeAll("followingIds", to.getId());

        // 更新user的列表
        Query<User> updateQuery2 = udao.createQuery().field("_id")
                .equal(to.getId());
        UpdateOperations<User> ops2 = udao.createUpdateOperations()
                .removeAll("followingIds", from.getId());
        udao.update(updateQuery, ops);
        udao.update(updateQuery2, ops2);
        
        
        
        //log
        
        Log ulog = new UserLog();
        ulog.setOwnerId(from.getId());
        ulog.setTitle(from.getName());
        ulog.setTargetId(to.getId());
        ulog.setAction(Action.UNFOLLOW_USER);
        
        
        ldao.save(ulog);
        
    }

    public void answer(User user,Question question, String answerBody) {
        Answer answer = new Answer();
        answer.setBody(answerBody);
        answer.setAuthorId(user.getId());
        answer.setAuthorName(user.getName());

        answer.setQuestionId(question.getId());
        answer.setUpdateAt(new Date());

        user.setAnswerCount(user.getAnswerCount()+1);
        adao.save(answer);
        

        question.getAnswers().add(answer);
        qdao.save(question);
        
        
        Log alog = new AnswerLog();
        alog.setOwnerId(user.getId());
        alog.setTitle(answer.getBody());
        alog.setAnswerId(answer.getId());
        alog.setTargetId(answer.getId());
        alog.setAction(Action.NEW);
        alog.setTargetParentId(question.getId());
        alog.setTargetParentTitle(question.getTitle());
        
        
        ldao.save(alog);
        // 回答一个问题默认关注这个问题
        followQuestion(user,question);
    }

    public void followTopic(User user,Topic topic) {

        if (!user.getFollowedTopicIds().contains(topic.getId())) {
        	user.getFollowedTopicIds().add(topic.getId());

            List<ObjectId> tfs = topic.getFollowerIds();
            if (!tfs.contains(user.getId())) {
                tfs.add(user.getId());
                topicdao.save(topic);
            }
            
            udao.save(user);
            
            
            Log ulog = new UserLog();
            ulog.setOwnerId(user.getId());
            ulog.setTitle(user.getName());
            ulog.setTargetId(topic.getId());
            ulog.setAction(Action.FOLLOW_TOPIC);
            
            
            ldao.save(ulog);
        }
    }

    public void unfollowTopic(User user,Topic topic) {

        user.getFollowedTopicIds().remove(topic.getId());
        topic.getFollowerIds().remove(user.getId());

        
        Query<User> updateQuery = udao.createQuery().field("_id")
                .equal(user.getId());
        UpdateOperations<User> ups = udao.createUpdateOperations().removeAll(
                "followedTopicIds", topic.getId());

        Query<Topic> updateQuery2 = topicdao.createQuery().field("_id")
                .equal(topic.getId());
        UpdateOperations<Topic> ups2 = topicdao.createUpdateOperations().removeAll(
                "followerIds", user.getId());

        udao.update(updateQuery, ups);
        topicdao.update(updateQuery2, ups2);
        
        
        Log ulog = new UserLog();
        ulog.setOwnerId(user.getId());
        ulog.setTitle(user.getName());
        ulog.setTargetId(topic.getId());
        ulog.setAction(Action.UNFOLLOW_TOPIC);
        
        
        ldao.save(ulog);

    }

    public void followQuestion(User user,Question ques) {
        if (!user.getFollowedQuestionIds().contains(ques.getId())) {
        	user.getFollowedQuestionIds().add(ques.getId());

            List<ObjectId> qfs = ques.getFollowerIds();
            if (!qfs.contains(user.getId())) {
                qfs.add(user.getId());
                qdao.save(ques);
            }
            
            udao.save(user);
            
            //log
            
            UserLog ulog = new UserLog();
            ulog.setOwnerId(user.getId());
            ulog.setTitle(user.getName());
            ulog.setTargetId(ques.getId());
            ulog.setTargetAttr(ques.getTitle());
            ulog.setAction(Action.FOLLOW_ASK);
            
            
            ldao.save(ulog);
            
            add2FollowersTimeLine(user,ulog);

        }
    }

    public void unfollowQuestion(User user,Question ques) {

        user.getFollowedQuestionIds().remove(ques.getId());
        ques.getFollowerIds().remove(user.getId());

       
        Query<User> updateQuery = udao.createQuery().field("_id")
                .equal(user.getId());
        UpdateOperations<User> ups = udao.createUpdateOperations().removeAll(
                "followedQuestionIds", ques.getId());

        Query<Question> updateQuery2 = qdao.createQuery().field("_id")
                .equal(ques.getId());
        UpdateOperations<Question> ups2 = qdao.createUpdateOperations()
                .removeAll("followerIds", user.getId());

        udao.update(updateQuery, ups);
        qdao.update(updateQuery2, ups2);
        
        Log ulog = new UserLog();
        ulog.setOwnerId(user.getId());
        ulog.setTitle(user.getName());
        ulog.setTargetId(ques.getId());
        ulog.setAction(Action.UNFOLLOW_ASK);
        
        
        ldao.save(ulog);

    }

    public void save(User user) {
        
        udao.save(user);
    }

    
    
    private void add2FollowersTimeLine(User from ,Log log) {
        
        List<ObjectId> theFollowerIds = from.getFollowerIds();
        for(ObjectId idd : theFollowerIds) {
            User u = udao.get(idd);
            TimeLine timeline = u.getTimeline();
            if(null == timeline) {
                timeline = new TimeLine();
                tdao.save(timeline);
                u.setTimeline(timeline);
                udao.save(u);
            }
            timeline.getLogs().add(log);
            tdao.save(timeline);
        }

    }

	public User get(ObjectId viewedUserId) {
		
		return udao.get(viewedUserId);
	}

	public User findby(String email, String password) {
		Query<User> query = udao.createQuery().field("email").equal(email).field("password").equal(password);
		List<User> list = query.asList();
		return list.size() > 0 ? list.get(0):null;
	}

	public List<User> findAll() {
		
		QueryResults<User> result =  udao.find();
        List<User> users = result.asList();
		return users;
	}
}
